/**
 * 
 */
package com.lazyshopkeeper.front.api;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.lazyshopkeeper.front.common.Constant;
import com.taobao.api.ApiException;
import com.taobao.api.Constants;
import com.taobao.api.FileItem;
import com.taobao.api.TaobaoClient;
import com.taobao.api.TaobaoParser;
import com.taobao.api.TaobaoRequest;
import com.taobao.api.TaobaoResponse;
import com.taobao.api.TaobaoUploadRequest;
import com.taobao.api.internal.parser.json.ObjectJsonParser;
import com.taobao.api.internal.parser.xml.ObjectXmlParser;
import com.taobao.api.internal.util.RequestParametersHolder;
import com.taobao.api.internal.util.TaobaoHashMap;
import com.taobao.api.internal.util.TaobaoLogger;
import com.taobao.api.internal.util.TaobaoUtils;
import com.taobao.api.internal.util.WebUtils;

/**
 * 采用oauth2.0进行的免签名api调用客户端
 * 
 * @author xuyuqi
 * 
 */
public class OAuthTaobaoClient implements TaobaoClient {

	private static final String FORMAT = "format";
	private static final String METHOD = "method";
	private static final String ACCESS_TOKEN = "access_token";
	private static final String VERSION = "v";

	private String access_token;
	private String format = Constants.FORMAT_JSON;
	private String version = "2.0";

	private int connectTimeout = 0;
	private int readTimeout = 0;

	public OAuthTaobaoClient(String access_token) {
		this.access_token = access_token;
	}

	public OAuthTaobaoClient(String access_token,
			int connectTimeout, int readTimeout) {
		this.connectTimeout = connectTimeout;
		this.readTimeout = readTimeout;
	}

	public <T extends TaobaoResponse> T execute(TaobaoRequest<T> request)
			throws ApiException {
		TaobaoParser<T> parser;
		if (Constants.FORMAT_XML.equals(this.format)) {
			parser = new ObjectXmlParser<T>(request.getResponseClass());
		} else {
			parser = new ObjectJsonParser<T>(request.getResponseClass());
		}
		return _execute(request, parser);
	}

	public <T extends TaobaoResponse> T execute(TaobaoRequest<T> request,
			String session) throws ApiException {
		return execute(request);
	}

	private <T extends TaobaoResponse> T _execute(TaobaoRequest<T> request,
			TaobaoParser<T> parser) throws ApiException {
		Map<String, Object> rt = doPost(request);
		if (rt == null)
			return null;
		T tRsp = null;
		try {
			tRsp = parser.parse((String) rt.get("rsp"));
			tRsp.setBody((String) rt.get("rsp"));
		} catch (RuntimeException e) {
			TaobaoLogger.logBizError((String) rt.get("rsp"));
			throw e;
		}

		tRsp.setParams((TaobaoHashMap) rt.get("textParams"));
		if (!tRsp.isSuccess()) {
			TaobaoLogger.logErrorScene(rt, tRsp, Constant.APP_SERCET);
		}
		return tRsp;
	}

	private <T extends TaobaoResponse> Map<String, Object> doPost(
			TaobaoRequest<T> request) throws ApiException {
		Map<String, Object> result = new HashMap<String, Object>();
		RequestParametersHolder requestHolder = new RequestParametersHolder();
		TaobaoHashMap appParams = new TaobaoHashMap(request.getTextParams());
		requestHolder.setApplicationParams(appParams);

		// 添加协议级请求参数
		TaobaoHashMap protocalMustParams = new TaobaoHashMap();
		protocalMustParams.put(METHOD, request.getApiMethodName());
		protocalMustParams.put(VERSION, version);
		protocalMustParams.put(ACCESS_TOKEN, access_token);
		requestHolder.setProtocalMustParams(protocalMustParams);

		TaobaoHashMap protocalOptParams = new TaobaoHashMap();
		protocalOptParams.put(FORMAT, format);
		requestHolder.setProtocalOptParams(protocalOptParams);

//		StringBuffer urlSb = new StringBuffer(serverUrl);
		StringBuffer urlSb = new StringBuffer(Constant.OAUTH_API_URL);
		try {
			String sysMustQuery = WebUtils.buildQuery(
					requestHolder.getProtocalMustParams(),
					Constants.CHARSET_UTF8);
			String sysOptQuery = WebUtils.buildQuery(
					requestHolder.getProtocalOptParams(),
					Constants.CHARSET_UTF8);

			urlSb.append("?");
			urlSb.append(sysMustQuery);
			if (sysOptQuery != null & sysOptQuery.length() > 0) {
				urlSb.append("&");
				urlSb.append(sysOptQuery);
			}
		} catch (IOException e) {
			throw new ApiException(e);
		}

		String rsp = null;
		try {
			// 是否需要上传文件
			if (request instanceof TaobaoUploadRequest) {
				TaobaoUploadRequest<T> uRequest = (TaobaoUploadRequest<T>) request;
				Map<String, FileItem> fileParams = TaobaoUtils
						.cleanupMap(uRequest.getFileParams());
				rsp = WebUtils.doPost(urlSb.toString(), appParams, fileParams,
						connectTimeout, readTimeout);
			} else {
				rsp = WebUtils.doPost(urlSb.toString(), appParams,
						connectTimeout, readTimeout);
			}
		} catch (IOException e) {
			throw new ApiException(e);
		}
		result.put("rsp", rsp);
		result.put("textParams", appParams);
		result.put("protocalMustParams", protocalMustParams);
		result.put("protocalOptParams", protocalOptParams);
		result.put("url", urlSb.toString());
		return result;
	}

}
